﻿namespace Pub.Class
{
    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;

    public class ShareConnect : IDisposable
    {
        private bool disposed;

        public ShareConnect(string domain, string userName, string password) : this(domain, userName, password, LogonType.Interactive, LogonProvider.Default)
        {
        }

        public ShareConnect(string domain, string userName, string password, LogonType logonType, LogonProvider logonProvider)
        {
            IntPtr ptr;
            if (string.IsNullOrEmpty(userName))
            {
                throw new ArgumentNullException("userName");
            }
            if (string.IsNullOrEmpty(domain))
            {
                domain = ".";
            }
            int error = 0;
            if (LogonUser(userName, domain, password, logonType, logonProvider, out ptr))
            {
                if (!ImpersonateLoggedOnUser(ptr))
                {
                    error = GetLastError();
                }
            }
            else
            {
                error = GetLastError();
            }
            if (error != 0)
            {
                throw new Win32Exception(error);
            }
        }

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                RevertToSelf();
                this.disposed = true;
            }
        }

        ~ShareConnect()
        {
            this.Dispose(false);
        }

        [DllImport("Kernel32.dll")]
        private static extern int GetLastError();
        [DllImport("Advapi32.DLL")]
        private static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
        [DllImport("Advapi32.dll")]
        private static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, LogonType dwLogonType, LogonProvider dwLogonProvider, out IntPtr phToken);
        [DllImport("Advapi32.DLL")]
        private static extern bool RevertToSelf();
    }
}

